<template>
  <div class="float-ball" @contextmenu.prevent @mousedown="onMouseDown" @mouseup="onMouseUp" @mouseleave="onMouseUp">
    <GLTFViewer class="ball-inner" modelName="cat" />
    <!-- 水波纹动画层 -->
    <div class="ripple-container" ref="rippleContainer">
      <div class="ripple"></div>
      <div class="ripple"></div>
      <div class="ripple"></div>
    </div>
  </div>
</template>

<script>
import GLTFViewer from "./GLTFViewer.vue";
import { mapState, mapActions } from "vuex";
import { VoiceService } from "@/services/voiceService";
import imageMatcher from "@/utils/opencvTool";
import { listAppSupportFunctions } from "@/utils/appFunctionIndexer";
import { getProjectRoot } from '@/utils/projectRoot'

export default {
  name: "FloatingBall",
  components: {
    GLTFViewer,
  },
  data() {
    return {
      dragging: false,
      pressOffset: { x: 0, y: 0 },
      onMouseMoveHandler: null,
      onMouseUpHandler: null,
      voiceService: null,
      isVoiceInitialized: false,
      workDir: null, // 示例：["D://DeskTop"]
      unlistenWorkDirs: null,
    };
  },
  computed: {
    ...mapState(["voiceState", "sessionId"]),
  },
  watch: {
    sessionId(newSessionId) {
      console.log("SessionID变化:", newSessionId);
      if (newSessionId && !this.isVoiceInitialized) {
        this.initializeVoiceService();
      }
    },
  },
  async mounted() {
    console.log("FloatingBall组件已挂载");
    // 如果已有SessionID，立即初始化
    if (this.sessionId) {
      await this.initializeVoiceService();
    }
  },
  beforeDestroy() {
    // 清理资源
    if (this.voiceService) {
      this.voiceService.dispose();
    }
    if (typeof this.unlistenWorkDirs === "function") {
      this.unlistenWorkDirs();
      this.unlistenWorkDirs = null;
    }
  },
  async created() {
    // 初始化工作目录：读取持久化或回退桌面路径
    try {
      if (
        window.electronSettingsAPI &&
        typeof window.electronSettingsAPI.getWorkDirs === "function"
      ) {
        const dirs = await window.electronSettingsAPI.getWorkDirs();
        if (Array.isArray(dirs) && dirs.length) {
          this.workDir = dirs;
          console.log("[设置] 初始化工作目录:", this.workDir);
        }
      }
    } catch (err) {
      console.warn("[设置] 初始化工作目录失败:", err);
    }
    // 监听工作目录更新广播
    if (
      window.electronSettingsAPI &&
      typeof window.electronSettingsAPI.onWorkDirsUpdated === "function"
    ) {
      this.unlistenWorkDirs = window.electronSettingsAPI.onWorkDirsUpdated(
        (payload) => {
          const dirs = (payload && payload.workDirs) || [];
          if (Array.isArray(dirs) && dirs.length) {
            this.workDir = dirs;
            console.log("[设置] 工作目录已更新:", this.workDir);
          }
        }
      );
    }

    //  console.log(await this.$searchAndOpenFile(['D://DeskTop'], 'agc', { maxResults: 20 }));
    //  console.log(await this.$searchAndOpenApp('微信'));
    //  console.log(await this.$searchAndOpen("哈哈"));
    // window.electronSearchAPI.onStatusChange((s) => {
    // console.log("搜索状态变化:", s);
    // });
  },

  async beforeMount() {
    //  this.$simulateMouse({ x: 1035, y: 225 ,width: 210, height: 40,button: 'left' }).then((content) => {
    //   console.log("鼠标左键模拟："+JSON.stringify(content));
    //   this.$simulateKeyboard({ text: 'hello', combos: ['ctrl+a'],specialKeys: ['backspace','enter'] }).then(content => {
    //     console.log("键盘模拟："+JSON.stringify(content));
    //   })
    // })
    // this.$simulateScroll({"direction": "horizontal", "amount": 500}).then(content => {
    //   console.log("滚动模拟："+JSON.stringify(content));
    // })
    //  this.$simulateMouse({ x: 750, y: 570 ,width: 210, height: 40,button: 'left' }).then((content) => {
    //     console.log("鼠标左键模拟："+JSON.stringify(content));
    //  })
    // setTimeout(() => {
    //   this.$captureScreen().then((content) => {
    //     console.log(content);
    //   });
    // this.$simulateMouse({
    //   x: 601,
    //   y: 753,
    //   width: 45,
    //   height: 30,
    //   button: "left",
    // }).then((content) => {
    //   console.log("鼠标左键模拟：" + JSON.stringify(content));
    // });
    // }, 10000);
    // OpenCV 模板匹配测试
    // setTimeout(() => {
    //   this.$captureScreen().then((content) => {
    //     console.log(content);
    //     // 模板匹配测试
    //     console.log("模板匹配测试");
    //     window.testImage = imageMatcher;
    //     const sourceImage = content.filePath;
    //     const templateImage = 'file:///D://DeskTop/stop2.png';
    //     imageMatcher.locateTemplate(
    //       sourceImage,
    //       templateImage
    //     ).then((result) => {
    //       console.log("模板匹配结果:", result);
    //       this.$simulateMouse({
    //         x: result.x,
    //         y: result.y,
    //         width: result.width,
    //         height: result.height,
    //         button: "left",
    //       }).then((content) => {
    //         console.log("鼠标左键模拟：" + JSON.stringify(content));
    //       });
    //     });
    //   });
    // }, 10000);
    // listAppSupportFunctions().then((result) => {
    //   console.log("应用支持函数列表:", JSON.stringify(result));
    // });

    // setTimeout(() => {
    //   this.$simulateMouse({ x: 70, y: 40, width: 50, height: 30, button: 'doubleClick' }).then(res => console.log("双击模拟："+JSON.stringify(res)))

    // }, 5000);


    // setTimeout(() => {
    //   // 点击输入框
    //   this.$simulateMouse({
    //     x: 1048,
    //     y: 131,
    //     width: 395,
    //     height: 55,
    //     button: "left",
    //   }).then((selectInput) => {
    //     if (!selectInput.success) {
    //       console.log("点击输入框失败");
    //       return;
    //     }
    //     // 输入框全选》输入》回车
    //     // this.$simulateKeyboard({ combos: ['ctrl', 'a'], specialKeys: ['backspace'], order: ['combos', 'specialKeys'], waitBetweenStepsMs: 120 }).then((content) => {
    //     //   console.log("键盘模拟：" + JSON.stringify(content));
    //     // })
    //   })
    // }, 5000);

  },

  methods: {
    ...mapActions(["setRecording", "setWebSocketConnected", "setVoiceState"]),

    async onMouseDown(e) {
      console.log(
        "鼠标按下事件:",
        e.button,
        "语音服务状态:",
        this.isVoiceInitialized
      );

      // 支持左键（button === 0）和右键（button === 2）
      if (e.button !== 0 && e.button !== 2) return;

      // 如果是左键，只处理语音功能，不处理拖拽
      if (e.button === 0) {
        console.log("左键按下，开始语音录制");
        // 开始水波纹动画（不改样式，仅调用现有逻辑）
        this.startRippleAnimation();

        // voiceState 门控：非 idle 时提示温柔可爱的通知并不继续录制
        if (
          this.voiceState &&
          this.voiceState !== "playing" &&
          this.voiceState !== "idle"
        ) {
          let body = "我正忙着呢，请稍后再试试~";
          switch (this.voiceState) {
            case "recording":
              body = "我正在认真录音呢，轻轻松开再开始吧~";
              break;
            case "processing":
              body = "我在思考刚才的话，稍等一下哦~";
              break;
            default:
              body = "我正忙着呢，请稍后再试试~";
          }
          if (
            window.electronAPI &&
            typeof window.electronAPI.notify === "function"
          ) {
            window.electronAPI.notify({ title: "声声不息", body });
          } else {
            console.log("[通知] 声声不息:", body);
          }
          // 提示后不继续录制，避免与当前状态冲突
          return;
        }

        // 录音前停止播放
        this.voiceService.stopAudio();

        // 开始语音录制（仅在空闲状态下）
        if (this.isVoiceInitialized) {
          console.log("语音服务已初始化，开始录制");
          await this.startVoiceRecording();
        } else {
          console.warn("语音服务未初始化，无法录制");
          this.$emit("voiceError", "语音服务未初始化");
        }
        return;
      }
      // 右键处理拖拽功能
      this.dragging = true;
      this.pressOffset = { x: e.clientX, y: e.clientY };
      window.electronAPI.dragStart(this.pressOffset);

      this.onMouseMoveHandler = () => {
        if (!this.dragging) return;
        window.electronAPI.dragMove();
      };

      this.onMouseUpHandler = () => {
        this.dragging = false;
        window.electronAPI.dragEnd();
        window.removeEventListener("mousemove", this.onMouseMoveHandler);
        window.removeEventListener("mouseup", this.onMouseUpHandler);
      };

      window.addEventListener("mousemove", this.onMouseMoveHandler);
      window.addEventListener("mouseup", this.onMouseUpHandler);
    },

    onMouseUp(e) {
      // 如果是左键且在录制中，停止录制
      if (e.button === 0 && this.isVoiceInitialized) {
        this.stopVoiceRecording();
        // 停止水波纹动画
        this.stopRippleAnimation();
      }

      // 如果是右键，结束拖拽
      if (e.button === 2) {
        this.dragging = false;
        window.electronAPI.dragEnd();
        window.removeEventListener("mousemove", this.onMouseMoveHandler);
        window.removeEventListener("mouseup", this.onMouseUpHandler);
      }
    },

    async initializeVoiceService() {
      try {
        this.voiceService = new VoiceService();

        // 初始化语音服务
        await this.voiceService.initialize(this.sessionId);

        // 设置事件处理器
        this.setupVoiceServiceHandlers();

        this.isVoiceInitialized = true;
        console.log("语音服务初始化成功");
        this.$emit("voiceInitialized", true);
      } catch (error) {
        console.error("语音服务初始化失败:", error);
        this.$emit("voiceError", error.message);
      }
    },

    setupVoiceServiceHandlers() {
      if (!this.voiceService) return;

      // 连接状态处理
      this.voiceService.on("connected", () => {
        this.setWebSocketConnected(true);
        console.log("语音服务连接成功");
      });

      this.voiceService.on("disconnected", () => {
        this.setWebSocketConnected(false);
        console.log("语音服务连接断开");
      });

      // 录制状态处理
      this.voiceService.on("recordingStarted", () => {
        this.setRecording(true);
        this.setVoiceState("recording");
      });

      this.voiceService.on("recordingStopped", () => {
        this.setRecording(false);
        this.setVoiceState("processing");
      });

      // 音频播放处理
      this.voiceService.on("audioPlaying", () => {
        this.setVoiceState("playing");
      });

      this.voiceService.on("audioStopped", () => {
        this.setVoiceState("idle");
      });

      // 文本响应处理
      this.voiceService.on("textResponse", (message) => {
        console.log("收到文本响应:", message);
        this.setVoiceState("processing");
        // 这里可以显示文本响应或触发其他UI更新
        this.$emit("textResponse", message);
      });

      // 打开应用或文件响应处理
      this.voiceService.on("openAppMessage", async (message) => {
        console.log("收到打开工具请求:", message);
        this.setVoiceState("processing");

        let openAppObj = JSON.parse(message);
        let taskResults = "";
        // 打开应用或文件
        for (const e of [...JSON.parse(openAppObj.task)]) {
          let obj = null;
          if (e.type === "file") {
            obj = await this.$searchAndOpenFile(this.workDir, e.name, {
              maxResults: 20,
            });
          } else if (e.type === "app") {
            obj = await this.$searchAndOpenApp(e.name);
          } else {
            obj = await this.$searchAndOpen(e.name);
          }
          taskResults += obj.success
            ? e.name + "成功打开；"
            : e.name + "打开失败；";
        }

        // 将taskResults发送给后端
        this.voiceService.sendTextMessage(
          JSON.stringify({
            requestId: openAppObj.requestId,
            content: taskResults,
          })
        );
      });

      // 文件系统消息处理
      this.voiceService.on("fileSystemMessage", async (message) => {
        console.log("收到文件系统请求:", message);
        this.setVoiceState("processing");
        let messageObj = JSON.parse(message);
        let taskArr = JSON.parse(messageObj.task);
        // 按 order 升序排序（从小到大）
        taskArr.sort((a, b) => a.order - b.order);
        let taskResults = "";
        // TODO 处理文件系统请求
        for (const task of taskArr) {
          if (task.type === "createFile") {
            let obj = await this.$fileUtil.createFile(
              task.name,
              task.content !== undefined ? task.content : ""
            );
            obj.success
              ? (taskResults += task.name + "文件成功创建；")
              : (taskResults += task.name + "文件创建失败；");
            taskResults += "\n";
          } else if (task.type === "writeFile") {
            let obj = await this.$fileUtil.writeFile(task.name, task.content);
            obj.success
              ? (taskResults += task.name + "文件成功写入；")
              : (taskResults += task.name + "文件写入失败；");
            taskResults += "\n";
          } else if (task.type === "readFile") {
            let obj = await this.$fileUtil.readFile(task.name);
            // 响应后端
            this.voiceService.sendTextMessage(
              JSON.stringify({
                requestId: messageObj.requestId,
                file_content: obj.content,
              })
            );
            return;

            // let obj = await this.$fileUtil.readFile(task.name);
            // obj.success
            //   ? (taskResults +=
            //       task.name + "文件成功读取，内容为:" + obj.content + "；")
            //   : (taskResults += task.name + "文件读取失败；");
            // taskResults += "\n";
          } else if (task.type === "deleteFile") {
            let obj = await this.$fileUtil.deleteFile(task.name);
            obj.success
              ? (taskResults += task.name + "文件成功删除；")
              : (taskResults += task.name + "文件删除失败；");
            taskResults += "\n";
          } else if (task.type === "renameFile") {
            let obj = await this.$fileUtil.renameFile(
              task.name,
              task.toName,
              task.overwrite !== undefined ? task.overwrite : false
            );
            obj.success
              ? (taskResults +=
                task.name + "文件成功重命名为" + task.toName + "；")
              : (taskResults +=
                task.name + "文件重命名为" + task.toName + "失败；");
            taskResults += "\n";
          } else if (task.type === "createDir") {
            let obj = await this.$fileUtil.createDir(task.name);
            obj.success
              ? (taskResults += task.name + "目录成功创建；")
              : (taskResults += task.name + "目录创建失败；");
            taskResults += "\n";
          } else if (task.type === "deleteDir") {
            let obj = await this.$fileUtil.deleteDir(
              task.name,
              task.force !== undefined ? task.force : false
            );
            obj.success
              ? (taskResults += task.name + "目录成功删除；")
              : (taskResults += task.name + "目录删除失败；");
            taskResults += "\n";
          } else if (task.type === "readDir") {
            let obj = await this.$fileUtil.readDir(task.name);
            let processedResult = this.processReadDir(this.workDir[0], obj);
            processedResult.description = "“" + task.name + "”目录下的所有文件";
            // 响应后端
            this.voiceService.sendTextMessage(
              JSON.stringify({
                requestId: messageObj.requestId,
                content: processedResult,
              })
            );
            return;
          }
        }

        // 响应后端
        this.voiceService.sendTextMessage(
          JSON.stringify({
            requestId: messageObj.requestId,
            content: taskResults,
          })
        );
      });

      // 应用操作消息处理
      this.voiceService.on("appOperationMessage", async (message) => {
        console.log("收到应用操作请求:", message);
        this.setVoiceState("processing");
        let appOperationObj = JSON.parse(message);

        let taskResults = "";

        if (appOperationObj.get === true) {
          // 获取可操作应用和操作
          taskResults = await listAppSupportFunctions();
        } else {
          // 执行操作
          let operationObj = JSON.parse(appOperationObj.task);
          let appName = operationObj.appName;
          let operationArr = operationObj.operation;
          if (typeof (operationArr) === "string") {
            operationArr = JSON.parse(operationArr);
          }

          if (appName === undefined || operationArr === undefined || operationArr.length === 0) {
            taskResults = "暂时不支持该应用的操作；";
            this.voiceService.sendTextMessage(
              JSON.stringify({
                requestId: appOperationObj.requestId,
                content: taskResults,
              })
            );
            return;
          }
          console.log(operationArr);

          // 按 order 升序排序（从小到大）
          operationArr.sort((a, b) => a.order - b.order);
          for (let operation of operationArr) {
            // 获取项目根路径
            const projectRoot = await getProjectRoot();
            console.log(1);
            console.log(projectRoot);


            if (!projectRoot) {
              taskResults += appName + "的" + operation.operationName + "操作执行失败；";
              continue;
            }
            console.log(2);

            // 截屏
            let screenShot = await this.$captureScreen();
            if (!screenShot.success) {
              taskResults += appName + "的" + operation.operationName + "操作执行失败；";
              continue;
            }
            console.log(3);

            const sourceImage = screenShot.filePath;
            // 模板图片路径
            const templateImage = projectRoot + "/template/" + appName + "/" + operation.operationName + ".png";
            console.log(templateImage);

            // 定位元素
            const imageMatcherResult = await imageMatcher.locateTemplate(sourceImage, templateImage);
            console.log(imageMatcherResult);

            console.log(4);

            // 根据事件执行操作
            let operationType = operation.operationName.split("-")[1];
            if (operationType === "input") {
              // 点击输入框
              let selectInput = await this.$simulateMouse({
                x: imageMatcherResult.x,
                y: imageMatcherResult.y,
                width: imageMatcherResult.width,
                height: imageMatcherResult.height,
                button: "left",
              });
              if (!selectInput.success) {
                taskResults += appName + "的" + operation.operationName + "操作执行失败；";
                continue;
              }

              // 清空输入框内容
              await this.$simulateKeyboard({
                text: "",
                specialKeys: ["backspace"],
                combos: "ctrl+a"
              });


              // 输入框全选》输入》回车
              let keyboardResult = await this.$simulateKeyboard({
                text: operation.content,
                specialKeys: ["enter"],
                combos: "ctrl+a"
              });

              if (!keyboardResult.success) {
                taskResults += appName + "的" + operation.operationName + "操作执行失败；";
                continue;
              } else {
                taskResults += appName + "的" + operation.operationName + "操作执行成功；";
              }
            } else {
              console.log(5);
              let mouseResult = await this.$simulateMouse({
                x: imageMatcherResult.x,
                y: imageMatcherResult.y,
                width: imageMatcherResult.width,
                height: imageMatcherResult.height,
                button: operationType,
              });
              console.log(6);
              if (!mouseResult.success) {
                taskResults += appName + "的" + operation.operationName + "操作执行失败；";
                continue;
              } else {
                taskResults += appName + "的" + operation.operationName + "操作执行成功；";
              }
            }

          }
        }

        // 将taskResults发送给后端
        this.voiceService.sendTextMessage(
          JSON.stringify({
            requestId: appOperationObj.requestId,
            content: taskResults,
          })
        );
      });

      // 支持操作应用消息处理
      this.voiceService.on("supportOperationAppMessage", async (message) => {
        this.setVoiceState("processing");
        let requestId = message;

        let taskResults = await listAppSupportFunctions();
        // 发送支持操作应用消息
        this.voiceService.sendTextMessage(
          JSON.stringify({
            requestId: requestId,
            content: taskResults,
          })
        );

      });

      // 错误处理
      this.voiceService.on("error", (error) => {
        console.error("语音服务错误:", error);
        this.setVoiceState("idle");
        this.setRecording(false);
        this.$emit("voiceError", error);
      });
    },

    startRippleAnimation() {
      // 水波纹动画开始
      this.$refs.rippleContainer.classList.add("ripple-animation");
    },

    stopRippleAnimation() {
      // 水波纹动画结束
      this.$refs.rippleContainer.classList.remove("ripple-animation");
    },

    async startVoiceRecording() {
      if (!this.voiceService) return;

      try {
        const success = await this.voiceService.startRecording();
        if (success) {
          console.log("开始语音录制");
        }
      } catch (error) {
        console.error("开始录制失败:", error);
        this.$emit("voiceError", error.message);
      }
    },

    async stopVoiceRecording() {
      if (!this.voiceService) return;

      try {
        const success = await this.voiceService.stopRecording();
        if (success) {
          console.log("停止语音录制");
        }
      } catch (error) {
        console.error("停止录制失败:", error);
        this.$emit("voiceError", error.message);
      }
    },
    processReadDir(prefix, obj) {
      // 转义正则中的特殊字符（处理前缀中可能包含的特殊符号）
      const escapeRegExp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");

      // 筛选出type为file的对象，并处理路径
      const processedItems = (obj.items || [])
        .filter((item) => item.type === "file")
        .map((item) => {
          // 1. 替换路径前缀（只替换开头的前缀部分）
          let processedPath = item.path.replace(
            new RegExp(`^${escapeRegExp(prefix)}`),
            ""
          );
          // 2. 将所有反斜杠替换为正斜杠
          processedPath = processedPath.replace(/\\/g, "/");
          return processedPath;
        });

      return { items: processedItems };
    },
  },
};
</script>

<style scoped>
.float-ball {
  width: 100px;
  height: 100px;
  background: transparent;
  position: fixed;
  top: 0;
  left: 0;
  user-select: none;
  border-radius: 50%;
  overflow: hidden;
  z-index: 1000;
  display: flex;
  justify-content: center;
  align-content: center;
}

.ball-inner {
  width: 100%;
  height: 100%;
  z-index: 1;
}

.ripple-container {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 1;
  border-radius: 50%;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 波纹基础样式 */
.ripple {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: rgba(206, 255, 244, 0.6);
  transform: translate(-50%, -50%) scale(0);
}

.ripple-animation>.ripple {
  animation: ripple 1.4s linear infinite;
}

/* 多层波纹设置不同延迟 */
.ripple:nth-child(2) {
  animation-delay: 0.8s;
}

.ripple:nth-child(3) {
  animation-delay: 1.2s;
}

/* 波纹动画 */
@keyframes ripple {
  30% {
    transform: translate(-50%, -50%) scale(0.4);
    opacity: 0.7;
  }

  80% {
    transform: translate(-50%, -50%) scale(0.8);
    opacity: 0.2;
  }

  to {
    transform: translate(-50%, -50%) scale(1);
    opacity: 0;
  }
}
</style>